package com.supplychain.scm.core.dinger.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.supplychain.scm.core.dinger.annotation.DingerTalk;
import com.supplychain.scm.core.dinger.config.DingerRootSend;
import com.supplychain.scm.core.dinger.config.IDingerProperties;
import com.github.jaemon.dinger.core.entity.DingerRequest;
import com.github.jaemon.dinger.core.entity.enums.MessageSubType;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author fengshaoyu
 * @version 1.0.0
 * <p>钉钉配置</p>
 * @date 2022/5/8 15:25
 */
@Slf4j
public class DingDingUtils {

    private static DingerRootSend dingerSender;

    public void setDingerSender(DingerRootSend dingerSender) {
        DingDingUtils.dingerSender = dingerSender;
    }

    /**
     * 发送text类型消息
     *
     * @param msg 消息
     */
    public static void sendTextMsg(String msg) {
        dingerSender.send(MessageSubType.TEXT, DingerRequest.request(msg));
    }

    /**
     * 发送Markdown类型消息
     *
     * @param msg 消息
     */
    public static void sendMarkdownMsg(String msg) {
        sendMarkdownMsg(msg,"消息发送");
    }

	/**
	 * 发送Markdown类型消息
	 *
	 * @param msg 消息
	 */
	public static void sendMarkdownMsg(String msg,String title) {
		dingerSender.send(MessageSubType.MARKDOWN, DingerRequest.request(msg,title));
	}

	public static void sendMarkdownMsg(String msg, Class<? extends IDingerProperties>[] properties,boolean defaultRoot) {
		sendMarkdownMsg(msg,"消息发送",properties,defaultRoot);
	}

	public static void sendMarkdownMsg(String msg, String title, Class<? extends IDingerProperties>[] properties,boolean defaultRoot) {
		dingerSender.send(MessageSubType.MARKDOWN, DingerRequest.request(msg,title),properties,defaultRoot);
	}

    /**
     * 发送自定义消息类型的消息
     *
     * @param messageSubType 消息类型
     * @param msg 消息
     */
    public static void sendMsg(MessageSubType messageSubType, String msg) {
        dingerSender.send(messageSubType, DingerRequest.request(msg));
    }

    /**
     * 异常消息通知
     * @param throwable 异常消息
     * @param args   异常入参
     * @return String
     */
    public static String dingExceptionMsg(Throwable throwable, String className, Object[] args, DingerTalk dingTalk, String active){
		ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		String bizCode = Optional.ofNullable(servletRequestAttributes).map(ServletRequestAttributes::getRequest).map(request -> request.getHeader("biz_code")).orElse("");
		String describe = dingTalk.describe();
		boolean stack = dingTalk.isStackTrace();
		String stackTrace = Arrays.stream(throwable.getStackTrace()).map(traceElement -> "\r\tat " + traceElement).collect(Collectors.joining());
		String msg = "\n" + "> - 环境: active\n" +
				"> - 业务编码: bizCode\n" +
				"> - 告警时间: "+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +"\n"+
                "> - className\n" +
				(StringUtils.hasText(MDC.get("requestId")) ? "> - Request Id: " + MDC.get("requestId") + "\n" : "") +
				"> - Args: args\n" +
				(StringUtils.hasText(describe) ? "> - 描述：describe\n" : "") +
                "> - 当前的问题是:\n" +
                "> message" + "\n" +
				(stack ? "* StackTrace: " + stackTrace + "\n" : "");
		log.warn("{} 钉钉异常AOP捕获 error = {}",className,stackTrace);
		return msg.replace("active", active)
				.replace("bizCode", bizCode)
				.replace("className", className)
				.replace("args", JSON.toJSONString(args, SerializerFeature.IgnoreErrorGetter))
				.replace("describe", describe)
				.replace("message", throwable.toString());
				//.replace("stackTrace", " <details>  <summary> 点击显示详情 </summary>  <pre> ".concat(stackTrace).concat(" </pre> </details> "));
    }

	/**
	 * 订单消息通知
	 * @param message 异常消息
	 * @param orderNo 异常订单号
	 * @return String
	 */
	public static String orderMsg(String message, String orderNo){
		String msg = "\n" + "> - 告警时间: "+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "\n" +
				"> - 订单号: orderNo\n" +
				"> - 当前的问题是:\n" +
				"> message";
		return msg.replace("orderNo", orderNo).replace("message", message);
	}
}